import axios from 'axios';
import { message } from 'antd';

// import _ from 'lodash';
import qs from 'qs';
import NProgress from 'nprogress';
import TokenApi from '@/api/base.js';
import 'nprogress/nprogress.css';

message.config({
  duration: 2,
  maxCount: 3
});
NProgress.configure({ showSpinner: false });
const http = axios.create({
  // baseURL: url, // 设置请求的base url
  timeout: 300000, // 超时时长5分钟,
  crossDomain: true
});

http.defaults.headers.post['Content-Type'] = 'multipart/form-data;application/json;charset=UTF-8;';

// loading对象
// let loading;

// 当前正在请求的数量
let needLoadingRequestCount = 0;

// 显示loading
function showLoading() {
  // 后面这个判断很重要，因为关闭时加了抖动，此时loading对象可能还存在，
  // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
  if (needLoadingRequestCount === 0) {
    NProgress.start();
  }
  needLoadingRequestCount++;
}

// 隐藏loading
function hideLoading() {
  needLoadingRequestCount--;
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); // 做个保护
  if (needLoadingRequestCount === 0) {
    NProgress.done();
  }
}

// 添加请求拦截器
let tempConfig = '';
// const isUseBaseToken = true; // 是否使用基础token
http.interceptors.request.use(
  config => {
    // 判断当前请求是否设置了不显示Loading
    tempConfig = config;
    tempConfig.url = decodeURI(encodeURI(tempConfig.url).replace('%E2%80%8B', ''));
    const whiteList = ['/connect/token'];
    whiteList.filter(item => {
      if (config.url.indexOf(item) !== -1) {
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded;';
        config.data = qs.stringify(config.data);
        return config;
      }
      return config;
    });
    if (config.headers.showLoading !== false) {
      showLoading();
    }
    const { token } = sessionStorage;
    if (token) {
      config.headers.common.Authorization = `Bearer ${token}`;
    }
    if (
      typeof config.data === 'string' &&
      config.data &&
      config.data.indexOf('refresh_token') !== -1
    ) {
      delete config.headers.common.Authorization;
    }
    return config;
  },
  err => {
    // 判断当前请求是否设置了不显示Loading
    if (tempConfig.headers.showLoading !== false) {
      hideLoading();
    }
    message.error('请求超时!');
    return Promise.resolve(err);
  }
);

let isRefreshToken = false; // 正在刷新token
let retryRequests = [];
let refreshCount = 0;
// 刷新token方法
async function refreshTokenFuc(config) {
  if (!isRefreshToken) {
    isRefreshToken = true;
    const temp = {
      client_id: 'login',
      client_secret: '123456',
      grant_type: 'refresh_token',
      refresh_token: sessionStorage.refreshToken
    };
    TokenApi.userToken(temp)
      .then(res => {
        const { data } = res;
        sessionStorage.token = data.access_token;
        sessionStorage.refreshToken = data.refresh_token;
        window.location.reload();
      })
      .catch(() => {
        if (refreshCount === 3 || error.status === 400) {
          refreshCount = 0;
          message.error('登录信息已过期，请重新登录!');
          isRefreshToken = false;
          setTimeout(() => {
            window.location.href = '/login';
          }, 1500);
        } else {
          refreshTokenFuc(config);
        }
      });
  }
  return new Promise(resolve => {
    retryRequests.push(token => {
      config.headers.Authorization = `Bearer ${token}`;
      resolve(http.request(config));
    });
  });
}

// 响应拦截器
http.interceptors.response.use(
  response => {
    // 判断当前请求是否设置了不显示Loading（不显示自然无需隐藏）
    if (response.config.headers.showLoading !== false) {
      hideLoading();
    }
    if (response.status === 401) {
      refreshTokenFuc(tempConfig);
      return Promise.reject(response);
    }
    // message.success(response.data.message);
    return response;
  },
  error => {
    hideLoading();
    if (error.response && error.response.status) {
      switch (error.response.status) {
        case 400:
          if (error.response.data.message) {
            message.error(error.response.data.message);
          } else if (error.response.data.error_description) {
            message.error(error.response.data.error_description);
          } else {
            message.error(error);
          }

          break;
        case 401:
          // 如有刷新token的需求,可放开以下代码
          refreshTokenFuc(error.config);
          break;
        case 500:
          message.error(error.response.data.message);
          break;
        default:
          break;
      }
      return Promise.reject(error.response);
    }
    message.error('温馨提示：数据获取失败');
    return Promise.reject(error.response);
  }
);

export default http;
